package com.helin.helinhealth.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.helin.helinhealth.dto.HealthRecordDTO;
import com.helin.helinhealth.dto.HealthReportDTO;
import com.helin.helinhealth.dto.HealthTrendDTO;
import com.helin.helinhealth.entity.HealthRecord;
import com.helin.helinhealth.entity.HealthReport;
import com.helin.helinhealth.mapper.HealthRecordMapper;
import com.helin.helinhealth.mapper.HealthReportMapper;
import com.helin.helinhealth.service.HealthService;
import com.helin.helinhealth.utils.UserContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 健康服务实现类
 */
@Slf4j
@Service
public class HealthServiceImpl extends ServiceImpl<HealthRecordMapper, HealthRecord> implements HealthService {

    @Autowired
    private HealthRecordMapper healthRecordMapper;
    
    @Autowired
    private HealthReportMapper healthReportMapper;

    /**
     * 记录健康数据
     *
     * @param recordDTO 健康记录DTO
     * @return 创建的健康记录ID
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long recordHealth(HealthRecordDTO recordDTO) {
        log.info("记录健康数据: {}", recordDTO);
        
        HealthRecord record = new HealthRecord();
        BeanUtils.copyProperties(recordDTO, record);
        
        // 设置用户ID和时间
        record.setUserId(UserContext.getCurrentUserOpenid());
        record.setCreateTime(LocalDateTime.now());
        record.setUpdateTime(LocalDateTime.now());
        
        // 保存记录
        save(record);
        
        log.info("健康数据记录成功: ID={}", record.getId());
        return record.getId();
    }

    /**
     * 获取健康趋势数据
     *
     * @param type 记录类型：1-血压 2-血糖
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 健康趋势DTO
     */
    @Override
    public HealthTrendDTO getHealthTrend(Integer type, LocalDate startDate, LocalDate endDate) {
        log.info("获取健康趋势: 类型={}, 开始日期={}, 结束日期={}", type, startDate, endDate);
        
        // 获取健康记录
        List<HealthRecord> records = getHealthRecordsByDateRange(type, startDate, endDate);
        
        if (records.isEmpty()) {
            log.warn("指定日期范围内没有健康记录");
            return new HealthTrendDTO();
        }
        
        // 构建趋势数据
        HealthTrendDTO trendDTO = new HealthTrendDTO();
        trendDTO.setType(type);
        
        List<LocalDate> dates = new ArrayList<>();
        List<String> values = new ArrayList<>();
        
        DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        
        for (HealthRecord record : records) {
            dates.add(record.getCreateTime().toLocalDate());
            values.add(record.getValue());
        }
        
        trendDTO.setDates(dates);
        trendDTO.setValues(values);
        
        // 生成趋势分析
        trendDTO.setAnalysis(generateAnalysis(type, records));
        
        return trendDTO;
    }

    /**
     * 获取用户健康记录列表
     *
     * @param type 记录类型：1-血压 2-血糖，null表示所有类型
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 健康记录列表
     */
    @Override
    public List<HealthRecordDTO> getHealthRecords(Integer type, LocalDate startDate, LocalDate endDate) {
        log.info("获取健康记录列表: 类型={}, 开始日期={}, 结束日期={}", type, startDate, endDate);
        
        // 获取健康记录
        List<HealthRecord> records = getHealthRecordsByDateRange(type, startDate, endDate);
        
        // 转换为DTO
        return records.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 生成健康报告
     *
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return 健康报告DTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public HealthReportDTO generateHealthReport(LocalDate startDate, LocalDate endDate) {
        log.info("生成健康报告: 开始日期={}, 结束日期={}", startDate, endDate);
        
        String userId = UserContext.getCurrentUserOpenid();
        
        // 获取所有类型的健康记录
        List<HealthRecord> records = getHealthRecordsByDateRange(null, startDate, endDate);
        
        if (records.isEmpty()) {
            log.warn("指定日期范围内没有健康记录，无法生成报告");
            return null;
        }
        
        // 生成报告内容
        StringBuilder content = new StringBuilder();
        content.append("健康报告摘要\n");
        content.append("报告时间范围: ").append(startDate).append(" 至 ").append(endDate).append("\n\n");
        
        // 血压记录
        List<HealthRecord> bloodPressureRecords = records.stream()
                .filter(r -> r.getType() == 1)
                .collect(Collectors.toList());
        
        if (!bloodPressureRecords.isEmpty()) {
            content.append("血压监测情况:\n");
            content.append("- 监测次数: ").append(bloodPressureRecords.size()).append("次\n");
            
            // 简单分析
            content.append("- ").append(generateAnalysis(1, bloodPressureRecords)).append("\n\n");
        }
        
        // 血糖记录
        List<HealthRecord> bloodGlucoseRecords = records.stream()
                .filter(r -> r.getType() == 2)
                .collect(Collectors.toList());
        
        if (!bloodGlucoseRecords.isEmpty()) {
            content.append("血糖监测情况:\n");
            content.append("- 监测次数: ").append(bloodGlucoseRecords.size()).append("次\n");
            
            // 简单分析
            content.append("- ").append(generateAnalysis(2, bloodGlucoseRecords)).append("\n\n");
        }
        
        content.append("建议: 请保持健康的生活方式，均衡饮食，适当运动，按时服药，定期复查。");
        
        // 创建健康报告
        HealthReport report = new HealthReport();
        report.setUserId(userId);
        report.setContent(content.toString());
        report.setStartDate(startDate);
        report.setEndDate(endDate);
        report.setCreateTime(LocalDateTime.now());
        report.setUpdateTime(LocalDateTime.now());
        report.setIsDeleted(false);
        
        // 保存报告到数据库
        healthReportMapper.insert(report);
        log.info("健康报告已保存: ID={}", report.getId());
        
        // 转换为DTO并返回
        HealthReportDTO reportDTO = new HealthReportDTO();
        BeanUtils.copyProperties(report, reportDTO);
        
        return reportDTO;
    }
    
    // =============== 辅助方法 ===============
    
    /**
     * 根据日期范围获取健康记录
     */
    private List<HealthRecord> getHealthRecordsByDateRange(Integer type, LocalDate startDate, LocalDate endDate) {
        String userId = UserContext.getCurrentUserOpenid();
        
        LocalDateTime startDateTime = startDate != null ? 
                startDate.atStartOfDay() : LocalDateTime.now().minusMonths(1);
        
        LocalDateTime endDateTime = endDate != null ? 
                endDate.plusDays(1).atStartOfDay() : LocalDateTime.now();
        
        // 构建查询条件
        LambdaQueryWrapper<HealthRecord> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HealthRecord::getUserId, userId);
        
        // 如果指定了类型，则按类型过滤
        if (type != null) {
            queryWrapper.eq(HealthRecord::getType, type);
        }
        
        queryWrapper.between(HealthRecord::getCreateTime, startDateTime, endDateTime);
        queryWrapper.orderByDesc(HealthRecord::getCreateTime);
        
        return list(queryWrapper);
    }
    
    /**
     * 将实体转换为DTO
     */
    private HealthRecordDTO convertToDTO(HealthRecord record) {
        HealthRecordDTO dto = new HealthRecordDTO();
        BeanUtils.copyProperties(record, dto);
        return dto;
    }
    
    /**
     * 生成简单的健康趋势分析
     */
    private String generateAnalysis(Integer type, List<HealthRecord> records) {
        if (records.isEmpty()) {
            return "无数据可分析";
        }
        
        if (type == 1) {
            // 血压分析
            return analyzeBloodPressure(records);
        } else if (type == 2) {
            // 血糖分析
            return analyzeBloodGlucose(records);
        }
        
        return "数据波动在正常范围内";
    }
    
    /**
     * 分析血压记录
     */
    private String analyzeBloodPressure(List<HealthRecord> records) {
        // 简单实现，实际应用中可能需要更复杂的分析算法
        int abnormalCount = 0;
        
        for (HealthRecord record : records) {
            String value = record.getValue();
            if (value.contains("/")) {
                String[] parts = value.split("/");
                if (parts.length == 2) {
                    try {
                        int systolic = Integer.parseInt(parts[0].trim());
                        int diastolic = Integer.parseInt(parts[1].trim());
                        
                        if (systolic > 140 || systolic < 90 || diastolic > 90 || diastolic < 60) {
                            abnormalCount++;
                        }
                    } catch (NumberFormatException e) {
                        log.warn("血压数据格式错误: {}", value);
                    }
                }
            }
        }
        
        double abnormalRate = (double) abnormalCount / records.size();
        
        if (abnormalRate > 0.5) {
            return "血压波动较大，建议咨询医生";
        } else if (abnormalRate > 0.2) {
            return "存在部分异常血压记录，请注意监测";
        } else {
            return "血压总体保持稳定";
        }
    }
    
    /**
     * 分析血糖记录
     */
    private String analyzeBloodGlucose(List<HealthRecord> records) {
        // 简单实现，实际应用中可能需要更复杂的分析算法
        int abnormalCount = 0;
        
        for (HealthRecord record : records) {
            String value = record.getValue();
            try {
                double glucoseValue = Double.parseDouble(value.trim());
                if (glucoseValue > 7.8 || glucoseValue < 3.9) {
                    abnormalCount++;
                }
            } catch (NumberFormatException e) {
                log.warn("血糖数据格式错误: {}", value);
            }
        }
        
        double abnormalRate = (double) abnormalCount / records.size();
        
        if (abnormalRate > 0.5) {
            return "血糖波动较大，建议咨询医生";
        } else if (abnormalRate > 0.2) {
            return "存在部分异常血糖记录，请注意监测";
        } else {
            return "血糖总体保持稳定";
        }
    }
}